#ifndef __UDT_SERVER__H
#define __UDT_SERVER__H
#include <Poco/ActiveMethod.h>
#include <Poco/Util/AbstractConfiguration.h>
#include <Poco/AutoPtr.h>

#ifndef WIN32
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <netdb.h>
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wspiapi.h>
#endif

#include <udt.h>

#include <Poco/ExpireLRUCache.h>
#include <Poco/Mutex.h>
#include <Poco/Tuple.h>
// need to split to 2 classes
class UDTServer
{
public:
	UDTServer(void);
	virtual ~UDTServer(void);
public:
		typedef Poco::Tuple<UDTSOCKET , UDTSOCKET> TReplayParam;
        Poco::ActiveMethod<void , void, UDTServer > Start;
		Poco::ActiveMethod<void , UDTSOCKET , UDTServer > QueueClient;
		Poco::ActiveMethod<void , TReplayParam , UDTServer> Replay;
        void Stop();
		void Setup(Poco::AutoPtr<Poco::Util::AbstractConfiguration> aConfiguration);
private:
        void StartImp();
		virtual void QueueClientImp(const UDTSOCKET&);
		void ReplayImpl(const TReplayParam&);

		void MakeFriends(UDTSOCKET aFirstSocket , UDTSOCKET aSecondSocket);

		// Send Data with exactly size
		bool SendData(UDTSOCKET aSocket,const char* aData, int aSize);
		bool SendData(UDTSOCKET aSocket , const std::string& aData);

		// receive Data with exactly size
		bool ReceiveData(UDTSOCKET aSocket , char* aData, int aSize);
		bool ReceiveData(UDTSOCKET aSocket , std::string& aData); // first 2 byte is length of string
private:

	UDTSOCKET	iServerSocket;
	int			iServerPort;
	Poco::ExpireLRUCache<Poco::UInt64 , UDTSOCKET > iSession2FirstSocketCache;
	Poco::Mutex iCacheMutex;
};

#endif
